#ifndef INPUTSET_H
#define INPUTSET_H

enum Button {
	IS_START,
	IS_U, IS_D, IS_L, IS_R,
	IS_A, IS_B, IS_X, IS_Y,
	IS_SL, IS_SR,
	IS_TOTAL
};

/**
 * A clocked input set.
 * Keeps track of two (current and previous) states
 * to provide rising/falling edge detection.
 *
 * NOTE: call clock() before changing values with set().
 */
class InputSet
{
public:
	bool current[ IS_TOTAL ];
	bool previous[ IS_TOTAL ];

	InputSet()
	{
		for ( int i = 0; i < IS_TOTAL; ++i ) {
			current[ i ] = false;
			previous[ i ] = false;
		}
	}

	/**
	 * Use before assigning values with set().
	 * Copies current[] to previous[].
	 */
	void clock()
	{
		for ( int i = 0; i < IS_TOTAL; ++i ) {
			previous[ i ] = current[ i ];
		}
	}

	/**
	 * Clears current[] and previous[].
	 */
	void clear()
	{
		for ( int i = 0; i < IS_TOTAL; ++i ) {
			previous[ i ] = 0;
			current[ i ] = 0;
		}
	}

	/**
	 * Sets specified button.
	 */
	void set( const Button i, const bool b )
		{ current[ i ] = b; }

	/**
	 * Sets specified button and also its previous state
	 * (suitable for consuming input)
	 */
	void put( const Button i, const bool b )
		{ current[i] = previous[i] = b; }

	/**
	 * Returns true if the specified Button is active.
	 */
	const bool get( const Button i ) const
		{ return current[ i ]; }

	bool& operator [] ( const Button i )
		{ return current[ i ]; }

	const bool operator [] ( const Button i ) const
		{ return current[ i ]; }

	/**
	 * Returns true on the rising edge of the specified Button.
	 */

	const bool rising( const Button i ) const
		{ return current[i] && !previous[i]; }

	/**
	 * Returns true on the falling edge of the specified Button.
	 */

	const bool falling( const Button i ) const
		{ return !current[i] && previous[i]; }
};

#endif

